package com.ooqiu.gaming.api;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.util.ArrayMap;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.sdk.app.PayTask;
import com.ooqiu.gaming.api.base.BaseResponse;
import com.ooqiu.gaming.api.base.ReqHelper;
import com.ooqiu.gaming.api.entities.ActRes;
import com.ooqiu.gaming.api.entities.Article;
import com.ooqiu.gaming.api.entities.ArticleDetailRes;
import com.ooqiu.gaming.api.entities.ArticleListRes;
import com.ooqiu.gaming.api.entities.CateRes;
import com.ooqiu.gaming.api.entities.MainContentRes;
import com.ooqiu.gaming.common.Constants;
import com.ooqiu.gaming.common.entities.GamingUser;
import com.ooqiu.gaming.components.retrofit.ConvertData;
import com.ooqiu.gaming.components.retrofit.convert.FastJsonConverterFactory;
import com.ooqiu.gaming.components.storage.UserStorage;
import com.ooqiu.gaming.db.Channel;
import com.ooqiu.gaming.ui.article_detail.CollectStatue;
import com.ooqiu.gaming.ui.feedback.UploadImg;
import com.ooqiu.gaming.ui.main.thread.index.content.IndexContentAdapter;
import com.ooqiu.gaming.ui.main.thread.interact.InteractEntity;
import com.ooqiu.gaming.ui.main.thread.interact.InteractRes;
import com.ooqiu.gaming.ui.person.history.HistoryRecord;
import com.ooqiu.gaming.utils.ListToStrUtil;
import com.ooqiu.gaming.utils.LogUtil;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.umeng.analytics.MobclickAgent;

import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * @author Eenie
 * @date 2017/11/21
 */

public class GamingApi {
    private GamingService mGamingService;
    private UserStorage mUserStorage;

    public GamingApi(OkHttpClient client, UserStorage userStorage) {
        mUserStorage = userStorage;
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constants.HOST)
                .client(client)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(FastJsonConverterFactory.create(userStorage))
                .build();
        mGamingService = retrofit.create(GamingService.class);
    }


//    @NeedLogin(force = true)
//    public Observable<List<Article>> fetchArticleList(int page, int typeId) {
//        Map<String, Object> params = new ArrayMap<>();
//        params.put("page", page);
//        params.put("pageSize", Constants.PAGE_SIZE);
//        params.put("typeid", typeId);
//        return mGamingService.fetchArticleList(params)
//                .map(new Function<ArticleListRes, List<Article>>() {
//                    @Override
//                    public List<Article> apply(ArticleListRes articleListRes) throws Exception {
//                        return articleListRes.getList();
//                    }
//                });
//    }

    public Observable<String> register(String mobile, String pwd, String code) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("mobile", mobile);
        params.put("password", pwd);
        params.put("code", code);
        return mGamingService.postData("register", ReqHelper.create(params))
                .map(new ConvertData<String>());
    }


    public Observable<String> fetchCode(String mobile, int type) {
        return fetchCode(mobile, type, "");
    }

    public Observable<String> fetchCode(String mobile, int type, String token) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("mobile", mobile);
        params.put("type", type);
        if (!TextUtils.isEmpty(token)) {
            params.put("token", token);
        }

        return mGamingService.postData("code", ReqHelper.create(params))
                .map(new ConvertData<String>());
    }

    public Observable<MainContentRes> fetchMainContent() {
        Map<String, Object> params = new ArrayMap<>();
        return mGamingService.postData("main", ReqHelper.create(params)
                .setLoginState(true, false))
                .map(new ConvertData<MainContentRes>(MainContentRes.class));
    }

    public Observable<MainContentRes> fetchVideoContent() {
        Map<String, Object> params = new ArrayMap<>();
        return mGamingService.postData("video/main", ReqHelper.create(params)
                .setLoginState(true, false))
                .map(new ConvertData<MainContentRes>(MainContentRes.class));
    }

    public Observable<GamingUser> login(String mobile, String pwd) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("mobile", mobile);
        params.put("password", pwd);
        return mGamingService.postData("login", ReqHelper.create(params))
                .map(new ConvertData<GamingUser>(GamingUser.class))
                .doOnNext(new Consumer<GamingUser>() {
                    @Override
                    public void accept(GamingUser user) throws Exception {
                        MobclickAgent.onProfileSignIn(user.getId(), "MOBILE");
                    }
                });
    }

    public Observable<GamingUser> dynamicLogin(String mobile, String code) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("mobile", mobile);
        params.put("code", code);
        return mGamingService.postData("activity/login", ReqHelper.create(params))
                .map(new ConvertData<GamingUser>(GamingUser.class))
                .doOnNext(new Consumer<GamingUser>() {
                    @Override
                    public void accept(GamingUser user) throws Exception {
                        MobclickAgent.onProfileSignIn(user.getId(), "MOBILE");
                    }
                });
    }

    public Observable<GamingUser> thirdLogin(final int type, String open_id, String nickName, String face) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        params.put("open_id", open_id);
        params.put("name", nickName);
        params.put("face", face);
        return mGamingService.postData("oLogin", ReqHelper.create(params))
                .map(new ConvertData<GamingUser>(GamingUser.class))
                .doOnNext(new Consumer<GamingUser>() {
                    @Override
                    public void accept(GamingUser user) throws Exception {
                        String src = "";
                        switch (type) {
                            case 1:
                                src = "QQ";
                                break;
                            case 2:
                                src = "WEIXIN";
                                break;
                            case 3:
                                src = "SINA";
                                break;
                        }
                        MobclickAgent.onProfileSignIn(user.getId(), src);
                    }
                });
    }

    public Observable<GamingUser> bindPhone(int type, String token, String mobile, String code) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        params.put("token", token);
        params.put("mobile", mobile);
        params.put("code", code);
        return mGamingService.postData("user/bind", ReqHelper.create(params))
                .map(new ConvertData<GamingUser>(GamingUser.class));
    }


    public Observable<CateRes> fetchNewsCate() {
        Map<String, Object> params = new ArrayMap<>();
        return mGamingService.postData("news/category", ReqHelper.create(params)
                .setLoginState(true, false))
                .map(new Function<BaseResponse, CateRes>() {
                    @Override
                    public CateRes apply(BaseResponse baseResponse) throws Exception {
                        CateRes cateRes = JSON.parseObject(baseResponse.getData(), CateRes.class);
                        return cateRes;
                    }
                });
    }

    public Observable<CateRes> fetchVideoCate() {
        Map<String, Object> params = new ArrayMap<>();
        return mGamingService.postData("video/category", ReqHelper.create(params)
                .setLoginState(true, false))
                .map(new Function<BaseResponse, CateRes>() {
                    @Override
                    public CateRes apply(BaseResponse baseResponse) throws Exception {
                        CateRes cateRes = JSON.parseObject(baseResponse.getData(), CateRes.class);
                        return cateRes;
                    }
                });
    }

    @Deprecated
    public Observable<String> saveArticleCate(List<Channel> userChannel, List<Channel> sysChannel) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("add_id", new ListToStrUtil<Channel>() {
            @Override
            public String getFieldStr(Channel data) {
                return data.getCat_id();
            }
        }.toStr(userChannel));
        params.put("delete_id", new ListToStrUtil<Channel>() {
            @Override
            public String getFieldStr(Channel data) {
                return data.getCat_id();
            }
        }.toStr(sysChannel));
        return mGamingService.postData("news/set", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<String>());
    }

    public Observable<String> saveArticleCate(List<Channel> userChannel) {
        Map<String, Object> params = new ArrayMap<>();
        String idx = "";
        for (int i = 0; i < userChannel.size(); i++) {
            idx = idx + (userChannel.size() - i) + ",";
        }
        if (!TextUtils.isEmpty(idx)) {
            idx = idx.substring(0, idx.length() - 1);
            params.put("add_idx", idx);
            params.put("add_id", new ListToStrUtil<Channel>() {
                @Override
                public String getFieldStr(Channel data) {
                    return data.getCat_id();
                }
            }.toStr(userChannel));
        }
        return mGamingService.postData("news/set", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<String>());
    }

    public Observable<String> saveVideoCate(List<Channel> userChannel) {
        Map<String, Object> params = new ArrayMap<>();
        String idx = "";
        for (int i = 0; i < userChannel.size(); i++) {
            idx = idx + (userChannel.size() - i) + ",";
        }
        if (!TextUtils.isEmpty(idx)) {
            idx = idx.substring(0, idx.length() - 1);
            params.put("add_idx", idx);
            params.put("add_id", new ListToStrUtil<Channel>() {
                @Override
                public String getFieldStr(Channel data) {
                    return data.getCat_id();
                }
            }.toStr(userChannel));
        }
        return mGamingService.postData("video/set", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<String>());
    }

    public Observable<List<Article>> fetchNewsList(int page, int cat_id) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("page", page);
        params.put("start", System.currentTimeMillis());
        params.put("cat_id", cat_id);
        return mGamingService.postData("news/all", ReqHelper.create(params))
                .map(new Function<BaseResponse, List<Article>>() {
                    @Override
                    public List<Article> apply(BaseResponse baseResponse) throws Exception {
                        ArticleListRes res = JSON.parseObject(baseResponse.getData(), ArticleListRes.class);
                        return res.getList();
                    }
                });
    }

    public Observable<List<Article>> fetchVideoList(int page, int cat_id) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("page", page);
        params.put("start", System.currentTimeMillis());
        params.put("cat_id", cat_id);
        return mGamingService.postData("video/all", ReqHelper.create(params))
                .map(new Function<BaseResponse, List<Article>>() {
                    @Override
                    public List<Article> apply(BaseResponse baseResponse) throws Exception {
                        ArticleListRes res = JSON.parseObject(baseResponse.getData(), ArticleListRes.class);
                        return res.getList();
                    }
                });
    }

    public Observable<List<InteractEntity>> fetchInteractList(int page, int status) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("page", page);
        params.put("start", System.currentTimeMillis());
        params.put("status", status);
        return mGamingService.postData("interact/list", ReqHelper.create(params))
                .map(new Function<BaseResponse, List<InteractEntity>>() {
                    @Override
                    public List<InteractEntity> apply(BaseResponse baseResponse) throws Exception {
                        InteractRes res = JSON.parseObject(baseResponse.getData(), InteractRes.class);
                        return res.getList();
                    }
                });
    }


    public Observable<GamingUser> fetchProfile(int type) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        return mGamingService.postData("user/info", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<GamingUser>(GamingUser.class));
    }


    public Observable<ArticleDetailRes> fetchArticleDetails(int news_id) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("news_id", news_id);
        params.put("token", mUserStorage.getToken());
        return mGamingService.postData("news/detail", ReqHelper.create(params))
                .map(new ConvertData<ArticleDetailRes>(ArticleDetailRes.class));
    }

    public Observable<ArticleDetailRes> fetchVideoDetails(int news_id) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("news_id", news_id);
        params.put("token", mUserStorage.getToken());
        return mGamingService.postData("news/detail", ReqHelper.create(params))
                .map(new ConvertData<ArticleDetailRes>(ArticleDetailRes.class));
    }


    public Observable<GamingUser> editProfile(String filed, String value) {
        Map<String, Object> params = new ArrayMap<>();
        params.put(filed, value);
        return mGamingService.postData("user/update", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<GamingUser>(GamingUser.class));
    }

    public Observable<String> feedback(String type, String content, String mobile, List<UploadImg> imgs) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        params.put("content", content);
        params.put("mobile", mobile);

        params.put("img", new ListToStrUtil<UploadImg>() {
            @Override
            public String getFieldStr(UploadImg data) {
                return data.getName();
            }

            @Override
            public String getDivisionFlag() {
                return ";";
            }
        }.toStr(imgs));

        return mGamingService.postData("advise", ReqHelper.create(params)
                .setLoginState(true, false))
                .map(new ConvertData<String>());
    }
//    public Observable<String> search() {
//        Map<String, Object> params = new ArrayMap<>();
////        params.put("type", type);
////        params.put("content", content);
////        params.put("mobile", mobile);
////        params.put("img", imgs);
//
//        return mGamingService.postData("advise", ReqHelper.create(params)
//                .setLoginState(true, false))
//                .map(new ConvertData<String>());
//    }


    public Observable<ArticleListRes> search(int type, int page, String key_word) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("page", page);
        params.put("key", key_word);
        params.put("start", System.currentTimeMillis());
        String path;
        switch (type) {
            case IndexContentAdapter.ITEM_VIDEO_CONTENT:
                path = "video/all";
                break;
            case IndexContentAdapter.ITEM_INTERACT_CONTENT:
//                path = "interact/list";
                path = "news/all";
                break;

            default:
                path = "news/all";
                break;
        }


        return mGamingService.postData(path, ReqHelper.create(params))
                .map(new ConvertData<ArticleListRes>(ArticleListRes.class));
    }

    /**
     * 收藏接口
     *
     * @param type    文章类型 1文章 2视频 3互动
     * @param newsId  文章的id
     * @param collect 是否收藏
     * @return
     */
    public Observable<String> collect(int type, int newsId, boolean collect) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        params.put("article_id", newsId);
        params.put("action", collect ? 1 : 2);
        return mGamingService.postData("user/collect", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<String>());
    }

    public Observable<List<Article>> fetchCollect(int type, int page) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        params.put("page", page);
        return mGamingService.postData("user/collectList", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new Function<BaseResponse, List<Article>>() {
                    @Override
                    public List<Article> apply(BaseResponse baseResponse) throws Exception {
                        ArticleListRes res = JSON.parseObject(baseResponse.getData(), ArticleListRes.class);
                        return res.getList();
                    }
                });
    }

    public Observable<HistoryRecord> fetchHistory(int page) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("start", System.currentTimeMillis());
        params.put("page", page);
        return mGamingService.postData("user/history", ReqHelper.create(params)
                .setLoginState(true, true))
                .map(new ConvertData<HistoryRecord>(HistoryRecord.class));
    }

    public Observable<CollectStatue> fetchCollectStatue(int news_id) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("news_id", news_id);
        return mGamingService.postData("news/collect", ReqHelper.create(params)
                .setLoginState(true, false))
                .map(new ConvertData<CollectStatue>(CollectStatue.class));
    }

    public Observable<List<String>> searchKeyWord(int type) {
        Map<String, Object> params = new ArrayMap<>();
        params.put("type", type);
        return mGamingService.postData("news/key", ReqHelper.create(params))
                .map(new ConvertData<List<String>>() {
                    @Override
                    public List<String> apply(BaseResponse baseResponse) throws Exception {
                        return JSON.parseArray(baseResponse.getData(), String.class);
                    }
                });
    }


    public Observable<ActRes> fetchAct() {
        Map<String, Object> params = new ArrayMap<>();
        return mGamingService.postData("activity/config", ReqHelper.create(params))
                .map(new ConvertData<ActRes>() {
                    @Override
                    public ActRes apply(BaseResponse baseResponse) throws Exception {
                        return JSON.parseObject(baseResponse.getData(), ActRes.class);
                    }
                });
    }

    public Observable<Map<String, String>> aliPay(Activity activity, final String orderInfo) {
        return Observable.just(activity)
                .subscribeOn(Schedulers.io())
                .map(new Function<Activity, Map<String, String>>() {
                    @Override
                    public Map<String, String> apply(Activity activity) throws Exception {
                        PayTask alipay = new PayTask(activity);

                        LogUtil.e(orderInfo);

                        return alipay.payV2(orderInfo, false);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread());

    }

    public void wxPay(Context context, String orderInfo) {
        final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, Constants.WX_APP_ID);
        msgApi.registerApp(Constants.WX_APP_ID);
        PayReq request = new PayReq();
        JSONObject orderInfoObj = JSON.parseObject(orderInfo);
        request.appId = orderInfoObj.getString("appid");
        request.partnerId = orderInfoObj.getString("partnerid");
        request.prepayId = orderInfoObj.getString("prepayid");
        request.packageValue = orderInfoObj.getString("package");
        request.nonceStr = orderInfoObj.getString("noncestr");
        request.timeStamp = orderInfoObj.getString("timestamp");
        request.sign = orderInfoObj.getString("sign");
        msgApi.sendReq(request);
    }


}
